package com.bjpowernode.manager;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Map;

@Component
public class JwtManager {

    @Value(value = "${jwt.secret}")
    private String secret;

    //1、生成，  2、验证， 3、解析

    /**
     * 生成JWT (Token)
     *
     */
    public String generateToken(String payload) {
        //组装头数据
        Map<String, Object> header = new HashMap<>();
        header.put("alg", "HS256");
        header.put("typ", "JWT");

        //链式编程
        return JWT.create()
                //头部
                .withHeader(header)

                //负载
                .withClaim("user", payload)

                //签名
                .sign(Algorithm.HMAC256(secret));
    }

    /**
     * 验证JWT
     *
     * @param token 要验证的jwt的字符串
     */
    public Boolean verifyToken(String token) {
        try {
            // 使用密钥创建一个jwt的验证器对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();

            //验证JWT，如果验证方法抛出异常则表示验证未通过，否则验证通过
            jwtVerifier.verify(token);

            //验证方法没有抛出异常，就表示验证通过，返回true
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 解析JWT的数据
     */
    public String parseToken(String token) {
        try {
            // 使用密钥创建一个jwt验证器对象
            JWTVerifier jwtVerifier = JWT.require(Algorithm.HMAC256(secret)).build();

            //验证JWT，得到一个解码后的jwt对象
            DecodedJWT decodedJWT = jwtVerifier.verify(token);

            Claim userClaim = decodedJWT.getClaim("user");
            String userString = userClaim.asString();

            System.out.println(userString);
            return userString;
        } catch (TokenExpiredException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
}